<?php
namespace app\common\logic;
use think\facade\Db;


class TuanPeriods
{

    /**
     * 购买
     */
    public function buy($user,$info,$per_num,$money_type='baodan1',$order_num=1,$is_admin=0,$cantuan=0){
        if($info['status']!=1){
            return ['msg'=>'您来晚了，已经结束'];
        }

        $total_num  = $per_num*$order_num;
        if($total_num>$info['rg_num_sy']){
            return ['msg'=>'剩余数量不足'];
        }

        $modtime = time();

        //先更新期数
        $save = [
            'rg_num_sy'=>array('exp','`rg_num_sy`-'.$total_num)
        ];

        if($info['qd_start_time']>$modtime){//预购开始了，抢购还未开始
            if($info['pre_end_time']<=$modtime){
                return ['msg'=>'请耐心等待抢单开始'];
            }

            if($info['pre_num_sy']<=0){
                return ['msg'=>'预购数量已满'];
            }else{
                if($total_num>$info['pre_num_sy']){
                    return ['msg'=>'预购数量还有'.$info['pre_num_sy'].'份'];
                }
            }
        }

        //前台购买
        if($is_admin==0){
            if($info['pre_start_time']>$modtime){
                return ['msg'=>'预购尚未开始，请耐心等待'];
            }


            //判断当期上限
            $have = Db::name('tuan_order')->where(['periods_id'=>$info['id'],'username'=>$user['username'],'is_ft'=>0])->sum('num');
            $sy = $info['maxnum']-$have;
            if($sy<=0){
                return ['msg'=>'当期购买已超上限'];
            }elseif($total_num>$sy){
                return ['msg'=>'当期购买最高'.$info['maxnum'].'份，您还能再购买'.$sy.'份'];
            }

            //判断最高购买
            if($total_num>$info['per_max']){
                return ['msg'=>'单次购买最高'.$info['per_max'].'份'];
            }

            //判断最低购买
            if($info['pre_end_time']>$modtime){//如果是预购
                if($info['pre_num_sy']==$total_num){//如果是仅剩的份数，忽略最小限制

                }else{
                    if($total_num<$info['per_min']){
                        return ['msg'=>'最低需购买'.$info['per_min'].'份'];
                    }
                }
            }else{//抢单开始了
                if($info['rg_num_sy']==$total_num){//如果是仅剩的份数，忽略最小限制

                }else{
                    if($total_num<$info['per_min']){
                        return ['msg'=>'最低需购买'.$info['per_min'].'份'];
                    }
                }
            }
        }

        //扣除预购,预购还未结束
        if($info['pre_end_time']>$modtime) {
            $ygnum = $total_num;
            if ($ygnum > $info['pre_num_sy']) {
                $ygnum = $info['pre_num_sy'];
            }

            if ($ygnum > 0) {
                $save['pre_num_sy'] = array('exp', '`pre_num_sy`-' . $ygnum);
            }
        }

        //成功
        if($total_num==$info['rg_num_sy']){
            $save['status'] = 3;
            $save['edit_time'] = $modtime;
        }

        $rs = Db::name('tuan_periods')->where(['id'=>$info['id']])->update($save);
        if(!$rs){
            return ['msg'=>'更新项目剩余数量失败'];
        }

        //扣钱
        if($cantuan==0){
            $rs = qianbao($user['user_id'],-($total_num*$info['price']),$money_type,'参与拼团','第'.$info['periods'].'期'.$info['cat_name']);
            if(!$rs['status']){
                return ['msg'=>$rs['msg']];
            }
        }

        //选出此会员有自动终止选项吗
        $zz_user = M('TuanZz')->where(['cat_id'=>$info['cat_id']])->find();//,'username'=>$user['username']

        //插入订单
        $insert = [];
        for($i=1;$i<=$order_num;$i++){
            $data = [];
            $data['periods_id'] = $info['id'];
            $data['periods'] = $info['periods'];
            $data['order_sn'] =$this->get_order_sn();
            $data['username'] = $user['username'];
            $data['user_id'] = $user['user_id'];
            $data['status'] = 1;
            $data['add_time'] = $modtime;
            $data['cat_id'] = $info['cat_id'];
            $data['cat_name'] = $info['cat_name'];
            $data['num'] = $per_num;
            $data['price'] = $info['price'];
            $data['img'] = $info['img'];
            $data['money_type'] = $money_type;
            $data['shouyi'] = $info['shouyi'];
            if($zz_user){//自动终结的期数
                $data['zz_qishu'] = $info['periods']+2*$zz_user['qishu'];
            }
            $insert[] = $data;
        }
        $rs = Db::name('tuan_order')->insertAll($insert);
        if(!$rs){
            return ['msg'=>'添加订单失败'];
        }

        //服务费--只计算新增的参团积分1
        $yeji = $total_num*$info['price'];

        if($money_type=='baodan1'){

            if($user['tjr_id']) {
                $alluser = Db::name('users')->getField('user_id,is_fws,fws_rate');
                $tjary = explode(",", $user['tjstr']);

                $jcrate = 0;

                //上级
                foreach ($tjary as $tuid) {
                    $tuser = $alluser[$tuid];
                    if ($tuser['is_fws']) {

                        $jjrate = $tuser['fws_rate'];

                        $rate = $jjrate - $jcrate;
                        if ($rate > 0) {
                            $jjprice = $yeji * $rate / 100;
                            if ($jjprice > 0) {
                                $rs = qianbao($tuid, $jjprice, 'shouyi', '服务费', $info['cat_name'] . '第' . $info['periods'] . '期，' . yc_phone($user['username']) . '参团业绩：' . $yeji);
                                if (!$rs['status']) {
                                    return ['status' => 0, 'msg' => '服务费：' . $rs['msg']];
                                }
                            }
                            $jcrate = $jjrate;
                        }
                    }
                }
                unset($alluser);
            }
        }

        //更新业绩
        $rs = $this->addyj($user,$yeji);
        if(!$rs['status']){
            return $rs;
        }

        return ['status'=>1];
    }

    /**
     * 获取订单 order_sn
     * @return string
     */
    public function get_order_sn()
    {
        $order_sn = null;
        // 保证不会有重复订单号存在
        while(true){
            $order_sn = date('YmdHis').rand(100000,999999); // 订单编号
            $order_sn_count = Db::name('tuan_order')->where("order_sn = ".$order_sn)->count();
            if($order_sn_count == 0)
                break;
        }

        return $order_sn;
    }

    //结算奖金
    public function jieSuan($info){
        $modtime = time();
        $ids = $info['id'];

        //先更新状态
        $rs = Db::name('tuan_periods')->where(['id'=>$ids])->update(['js_status'=>1,'js_time'=>$modtime]);
        if(!$rs){
            return ['msg'=>'更新结算状态失败'];
        }

        //选出这批人
        $alluser = Db::name('users')->getField('user_id,level,small_htlv,total_htlv,lj_xiaofei,username,is_zd');

        //拼装升级参数
        $ranks = M('UserLevel')->where(['rank'=>['gt',1]])->getField('rank',true);
        foreach($ranks as $rank){
            $tmp = "self".$rank;$tmp1 = "zt".$rank;$tmp2 = "team".$rank;
            $$tmp = tpCache('basic.level_buy'.$rank);
            $$tmp1 = tpCache('basic.level_ztyj'.$rank);
            $$tmp2= tpCache('basic.level_teamyj'.$rank)*10000;
        }

        //因为存在多期情况，培训费不是一条线奖金，这里需要判断所有人升级
        $sjsave1 = [];$insert1 = [];
        foreach($alluser as $uid=>$user){
            if($user['is_zd']==1) continue;//后台指定的，不判断

            $oldlv = $user['level'];
            $newlv = 1;//默认最低级别

            foreach($ranks as $rank){
                $tmp = "self".$rank;$tmp1 = "zt".$rank;$tmp2 = "team".$rank;
                if($user['lj_xiaofei']>=$$tmp && $user['small_htlv']>=$$tmp1 && $user['total_htlv']>=$$tmp2) {
                    $newlv = $rank;
                }
            }

            //这里也降级
            if($newlv!=$oldlv){
                //升级会员
                $sjsave1[] = [
                    'user_id'=>$uid,
                    'level'=>$newlv,
                ];
                //插入记录
                $insert = array();
                $insert['username'] = $user['username'];
                $insert['old'] = $oldlv;
                $insert['new'] = $newlv;
                $insert['w_time'] = $modtime;
                $insert['desc'] = '期数ID'.$ids.'-组团业绩'.$user['total_htlv']."，直拼业绩".$user['small_htlv'].'，参团'.$user['lj_xiaofei'];
                $insert1[]=$insert;

            }
        }

        if($sjsave1) {
            $rs = model('Users')->isUpdate()->saveAll($sjsave1);
            if (!$rs) {
                return ['status' => 0, 'msg' => '批量更新会员级别失败'];
            }

            $rs = Db::name('level_log')->insertAll($insert1);
            if (!$rs) {
                return ['status' => 0, 'msg' => '批量添加级别记录失败'];
            }
        }
        unset($sjsave1);
        unset($insert1);

        //级别更新后，重新选出
        $alluser = Db::name('users')->getField('user_id,tjr_id,tjstr,level,username,is_jm');

        //开始计算奖金--复投+新增，不含终止
        $orders = M('TuanOrder')->where(['periods_id'=>$ids,'status'=>1])->group('user_id')->getField('user_id,sum(num*price)');//,'money_type'=>'baodan1'
        //广告费
        $jjrate = tpCache('basic.tj_rate');
        if($jjrate>0) {
            foreach($orders as $uid=>$yeji){
                $user = $alluser[$uid];
                $tuser = $alluser[$user['tjr_id']];
                if($user['tjr_id'] && $tuser['is_jm']==1){
                    $jjprice = $yeji*$jjrate/100;

                    $rs = qianbao($user['tjr_id'],$jjprice,'yuqi','广告费',$info['cat_name'].'第'.$info['periods'].'期，'.yc_phone($user['username']).'业绩：'.$yeji,$ids);
                    if(!$rs['status']){
                        return ['status'=>0,'msg'=>'广告费：'.$rs['msg']];
                    }

                }
            }
        }


        //管理费
        $total = 0;//总业绩，用来计算最后的奖金
        foreach($orders as $uid=>$yeji){
            $total+=$yeji;

            $user = $alluser[$uid];
            if($user['tjr_id']){
                $tjary = explode(",",$user['tjstr']);

                $level = 1;$jcrate = 0;

                //上级
                foreach($tjary as $tuid){
                    $tuser = $alluser[$tuid];
                    $tjlevel = $tuser['level'];
                    if($tjlevel>$level){
                        $jjrate = tpCache('basic.level_jcrate'.$tjlevel);

                        $rate = $jjrate -$jcrate;
                        if($rate>0){
                            $jjprice = $yeji*$rate/100;
                            if($jjprice>0 && $tuser['is_jm']==1){
                                $rs = qianbao($tuid,$jjprice,'yuqi','管理费',$info['cat_name'].'第'.$info['periods'].'期，'.yc_phone($user['username']).'业绩：'.$yeji.'上一级比率'.$jcrate.'%'.'当前比率'.$jjrate.'%',$ids);
                                if(!$rs['status']){
                                    return ['status'=>0,'msg'=>'管理费：'.$rs['msg']];
                                }
                            }

                            $jcrate = $jjrate;
                        }
                        $level = $tjlevel;
                    }
                }
            }
        }
        unset($alluser);

        //培训费

        //找所有人
        $alllevel = Db::name('users')->where(['level'=>['gt',1]])->group('level')->getField('level,count(1)');

        if($alllevel){

            $save1=[];$insert1=[];
            foreach($alllevel as $lv=>$lvnum){
                $rate = tpCache('basic.level_pjrate'.$lv);
                $fhprice = ($total*$rate/100)/$lvnum;
                if($fhprice>=0.01){
                    // 选出这批人
                    $users = Db::name('users')->where(['level'=>$lv,'is_jm'=>1])->getField('user_id,username');
                    $uids = array_keys($users);
                    $wusers = Db::name('wallet')->where(['user_id'=>['in',$uids]])->getField('user_id,id,yuqi');
                    foreach($users as $uid=>$uname){
                        $wuser = $wusers[$uid];
                        //更新数值
                        $save1[]=[
                            'id'=>$wuser['id'],
                            'yuqi'=>$wuser['yuqi']+$fhprice,
                        ];
                        //插入明细
                        $data = [];
                        $data['user_id']=$uid;
                        $data['money']=$fhprice;
                        $data['yue']=$fhprice+$wuser['yuqi'];
                        $data['action']='培训费';
                        $data['desc']=$info['cat_name'].'第'.$info['periods'].'期'.'，业绩'.$total;
                        $data['w_time']=$modtime;
                        $data['periods_id'] = $ids;
                        $insert1[]=$data;
                    }
                    unset($users);unset($wusers);
                }
            }
            if($save1){
                $rs = model('Wallet')->isUpdate()->saveAll($save1);
                if(!$rs){
                    return ['msg'=>'批量更新预期钱包失败'];
                }else{
                    $rs=Db::name('yuqi_log')->insertAll($insert1);
                    if(!$rs){
                        return ['msg'=>'批量添加预期钱包记录失败'];
                    }
                }
            }
        }
        unset($alllevvel);


        return ['status'=>1];
    }

    //终止组团
    public function stop($id,$user_id=0){
        $map=['id'=>$id,'status'=>1,'zz_time'=>0];//只能终止一次
        if($user_id>0){
            $map['user_id'] = $user_id;
        }
        $order = M('TuanOrder')->where($map)->find();
        if(!$order){
            return ['msg'=>'订单状态有误'];
        }

        $last = M('TuanPeriods')->where(['cat_id'=>$order['cat_id']])->order('id desc')->find();
        if($order['periods']>=$last['periods']){
            return ['msg'=>'请等待下一期成功'];
        }
        if(($last['periods']-$order['periods'])!=1){
            return ['msg'=>'您来晚了，新的一期已经发布'];
        }

        if($last['status']!=3){
            return ['msg'=>'下一期成功之后，才能进行终止操作'];
        }

        //有个时间判断
        $hour = tpCache('basic.quit_hour');
        $over = $last['edit_time']+$hour*60*60;//N+1期成功之后，有个时间差

        $modtime = time();
        if($modtime>=$over){
            return ['msg'=>'您来晚了，终止时间已过'];
        }

        //更新订单状态
        $rs = Db::name('tuan_order')->where(['id'=>$id])->update(['status'=>2,'zz_time'=>$modtime]);
        if(!$rs){
            return ['msg'=>'更新订单终止状态失败'];
        }

        //如果n+2期开始了（上面421行已经封住），还可以终止的话，这里还需要对n+2的复投和新增数量进行变更

        //扣业绩
        if($order['is_ft']==0){
            $yeji = $order['num']*$order['price'];
            $user = M('Users')->where(['user_id'=>$order['user_id']])->find();
            $yeji = -$yeji;
            $rs = $this->addyj($user,$yeji);
            if(!$rs['status']) {
                return $rs;
            }
        }

        return ['status'=>1];
    }

    //恢复
    public function huifu($id,$user_id=0){
        $map=['id'=>$id,'status'=>2,'hf_time'=>0];//只能恢复一次
        if($user_id>0){
            $map['user_id'] = $user_id;
        }
        $order = M('TuanOrder')->where($map)->find();
        if(!$order){
            return ['msg'=>'订单状态有误'];
        }
        $modtime = time();

        $last = M('TuanPeriods')->where(['cat_id'=>$order['cat_id']])->order('id desc')->find();
        $cha = $last['periods']-$order['periods'];
        //N-1 或N-2 未开始抢单
        if(!($cha==1 || ($cha==2 && $last['qd_start_time']>$modtime && $last['status']==1))){
            return ['msg'=>'恢复时间已过'];
        }

        //更新订单状态
        $rs = Db::name('tuan_order')->where(['id'=>$id])->update(['status'=>1,'hf_time'=>$modtime]);
        if(!$rs){
            return ['msg'=>'更新订单状态失败'];
        }

        //更新已经发布的期数
        if($cha==2) { //N+2

            //复投新增数量变更
            $ftnum = $order['num']*(100+$order['shouyi'])/100;

            $ftnum1 = ceil($ftnum);
            $save = [
                'ft_num'=>array('exp','`ft_num`+'.$ftnum1),
                'rg_num'=>array('exp','`rg_num`-'.$ftnum1),
                'rg_num_sy'=>array('exp','`rg_num_sy`-'.$ftnum1),
            ];

            $rs = Db::name('tuan_periods')->where(['id'=>$last['id']])->update($save);
            if(!$rs){
                return ['msg'=>'更新N+2期复投数量失败'];
            }

            //n+2期已经产生了复投订单
            if($last['is_ft']==1){
                $data = [];
                $data['periods_id'] = $last['id'];
                $data['periods'] = $last['periods'];
                $data['order_sn'] = $this->get_order_sn();
                $data['username'] = $order['username'];
                $data['user_id'] = $order['user_id'];
                $data['status'] = 1;
                $data['add_time'] = $modtime;
                $data['cat_id'] = $order['cat_id'];
                $data['cat_name'] = $order['cat_name'];
                $data['num'] = $ftnum;
                $data['price'] = $order['price'];
                $data['img'] = $order['img'];
                $data['money_type'] = $order['money_type'];
                $data['is_ft'] = 1;
                $data['up_id'] = $order['id'];
                $data['shouyi'] = $last['shouyi'];


                $rs = Db::name('tuan_order')->insert($data);
                if (!$rs) {
                    return ['msg' => '添加复投订单失败'];
                }
            }
        }

        //新增业绩恢复
        if($order['is_ft']==0){
            $user = M('Users')->where(['user_id'=>$order['user_id']])->find();
            $rs = $this->addyj($user,$order['num']*$order['price']);
            if(!$rs['status']) {
                return $rs;
            }
        }


        return ['status'=>1];
    }

    public function addyj($user,$yeji){
        if($yeji>0){
            $save = array('lj_xiaofei'=>array('exp','`lj_xiaofei`+'.$yeji));
        }else{
            $save = array('lj_xiaofei'=>array('exp','`lj_xiaofei`-'.abs($yeji)));
        }

        $rs = Db::name('users')->where(['user_id'=>$user['user_id']])->save($save);

        if(!$rs){
            return ['status'=>0,'msg'=>'更新参团业绩失败'];
        }

        if($user['tjr_id']){
            if($yeji>0) {
                $save = array('small_htlv' => array('exp', '`small_htlv`+' . $yeji));
            }else{
                $save = array('small_htlv' => array('exp', '`small_htlv`-' . abs($yeji)));
            }
            $rs = Db::name('users')->where(['user_id'=>$user['tjr_id']])->save($save);
            if(!$rs){
                return ['status'=>0,'msg'=>'更新直拼业绩失败'];
            }

            //更新所有上级会员
            $tjary = explode(",",$user['tjstr']);
            $save1 = [];
            foreach($tjary as $tuid){
                $save  = [
                    'user_id'=>$tuid
                ];
                if($yeji>0){
                    $save['total_htlv']  = array('exp', '`total_htlv`+' . $yeji);
                }else{
                    $save['total_htlv']  = array('exp', '`total_htlv`-' . abs($yeji));
                }
                $save1[] = $save;
            }
            $rs = model('Users')->isUpdate()->saveAll($save1);

            if(!$rs){
                return ['status'=>0,'msg'=>'更新组团业绩失败'];
            }

        }

        return ['status'=>1];
    }

    //撤销
    public function cancel($id){
        $map=['id'=>$id,'status'=>1,'is_ft'=>0];

        $order = M('TuanOrder')->where($map)->find();
        if(!$order){
            return ['msg'=>'订单状态有误'];
        }
        $modtime = time();

        $pe = M('TuanPeriods')->where(['id'=>$order['periods_id']])->find();
        if($pe['status']!=1){
            return ['msg'=>'期数状态有误'];
        }

        //更新订单状态
        $rs = Db::name('tuan_order')->where(['id'=>$id])->update(['status'=>0,'cx_time'=>$modtime]);
        if(!$rs){
            return ['msg'=>'更新订单状态失败'];
        }

        //退钱
        $money = $order['num']*$order['price'];
        $rs = qianbao($order['user_id'],$money,$order['money_type'],'撤销拼团','订单'.$order['order_sn']);
        if(!$rs['status']){
            return ['msg'=>$rs['msg']];
        }

        //业绩回退
        $user = M('Users')->where(['user_id'=>$order['user_id']])->find();
        $rs = $this->addyj($user,-$money);
        if(!$rs['status']) {
            return $rs;
        }

        $save =[
            'rg_num_sy' => array('exp', '`rg_num_sy`+' . $order['num']),
        ];

        $rs = Db::name('tuan_periods')->where(['id'=>$order['periods_id']])->update($save);
        if(!$rs){
            return ['msg'=>'增加期数认购数量失败'];
        }

        return ['status'=>1];
    }

}